package com.gitee.wsl.common.chart.render.shape.plot

import android.graphics.*
import com.gitee.wsl.common.chart.model.PlotDot
import com.gitee.wsl.common.chart.render.shape.plot.PlotDotRender.Companion.plotDotRender
import com.gitee.wsl.common.ui.draw.type.DotStyle
import com.gitee.wsl.math.Math
import com.gitee.wsl.jvm.math.div


/**
 * @ClassName PlotDotRender
 * @Description  绘制交叉点的形状
 * @author XiongChuanLiang<br/>(xcl_168@aliyun.com)
 *
 */
class PlotDotRender {
     val fillPaint: Paint by lazy {
         Paint().apply {
             color = Color.WHITE
             style = Paint.Style.FILL
             isAntiAlias = true
         }
     }

     val path: Path = Path()

     val rect = RectF()

    /**
     * 绘制线上的坐标点
     *
     * @param canvas 画布
     * @param pDot    点类型
     * @param cirX    x坐标
     * @param cirY    Y坐标
     * @param paint    画笔
     */
    fun renderDot(
        canvas: Canvas, pDot: PlotDot,
        cirX: Float, cirY: Float, paint: Paint
    ): RectF {
        val radius = pDot.dotRadius
        if (radius.compareTo(0.0f) == 0 || radius.compareTo(0.0f) == -1) {
            return RectF(0.0f, 0.0f, 0.0f, 0.0f)
        }
        val left = cirX - radius
        val top = cirY - radius
        val right = cirX + radius
        val bottom = cirY + radius
        if (DotStyle.DOT == pDot.dotStyle || DotStyle.RING == pDot.dotStyle || DotStyle.X == pDot.dotStyle) {
            rect.left = left
            rect.top = top
            rect.right = right
            rect.bottom = bottom
        }
        when (pDot.dotStyle) {
            DotStyle.DOT -> canvas.drawCircle(cirX, cirY, radius, paint)
            DotStyle.RING -> renderRing(canvas, paint, radius, pDot, cirX, cirY)
            DotStyle.RING2 -> renderRing2(canvas, paint, radius, pDot, cirX, cirY)
            DotStyle.TRIANGLE -> renderTriangle(canvas, paint, radius, cirX, cirY)
            DotStyle.PRISMATIC ->            //renderPrismatic(canvas,paint,radius,right,bottom,left );
                renderPrismatic(canvas, paint, radius, cirX, cirY)
            DotStyle.RECT -> renderRect(canvas, paint, radius, cirX, cirY)
            DotStyle.X -> renderX(canvas, paint)
            DotStyle.CROSS -> renderCross(canvas, paint, radius, cirX, cirY)
            DotStyle.HIDE -> {}
        }
        return rect
    }

    private fun renderRing(
        canvas: Canvas, paint: Paint, radius: Float,
        pDot: PlotDot, cX: Float, bottom: Float
    ) {
        val ringRadius = radius * 0.7f // MathHelper.getInstance().mul(radius, 0.7f);		
        canvas.drawCircle(cX, bottom, radius, paint)
        fillPaint.color = pDot.ringInnerColor
        canvas.drawCircle(cX, bottom, ringRadius, fillPaint)
    }

    private fun renderRing2(
        canvas: Canvas, paint: Paint, radius: Float,
        pDot: PlotDot, cX: Float, bottom: Float
    ) {
        var ringRadius = radius * 0.7f // MathHelper.getInstance().mul(radius, 0.7f);		
        canvas.drawCircle(cX, bottom, radius, paint)
        fillPaint.color = pDot.ringInnerColor
        canvas.drawCircle(cX, bottom, ringRadius, fillPaint)
        ringRadius = radius * 0.3f
        fillPaint.color = pDot.ring2InnerColor
        canvas.drawCircle(cX, bottom, ringRadius, fillPaint)
    }

    private fun renderTriangle(
        canvas: Canvas,
        paint: Paint,
        radius: Float,
        cirX: Float,
        cirY: Float
    ) {
        val halfRadius =  Math.div(radius, 2f)
        val triangleHeight = radius + radius / 2
        path.reset()
        path.moveTo(cirX - radius, cirY + halfRadius)
        path.lineTo(cirX, cirY - triangleHeight)
        path.lineTo(cirX + radius, cirY + halfRadius)
        path.close()
        canvas.drawPath(path, paint)
        path.reset()
        rect.left = cirX - radius
        rect.top = cirY - triangleHeight
        rect.right = cirX + radius
        rect.bottom = cirY + halfRadius
    }

    private fun renderPrismatic(
        canvas: Canvas, paint: Paint,
        radius: Float, cirX: Float, cirY: Float
    ) {
        path.reset()
        val left = cirX - radius
        val right = cirX + radius
        val centerX = left + (right - left) / 2
        val top = cirY - radius
        val bottom = cirY + radius
        path.moveTo(centerX, top)
        path.lineTo(left, cirY)
        path.lineTo(centerX, bottom)
        path.lineTo(right, cirY)
        path.lineTo(centerX, top)
        path.close()
        canvas.drawPath(path, paint)
        path.reset()
        rect.left = left
        rect.top = top
        rect.right = right
        rect.bottom = bottom
    }

    private fun renderRect(canvas: Canvas, paint: Paint, radius: Float, cirX: Float, cirY: Float) {
        paint.style = Paint.Style.FILL
        rect.left = cirX - radius
        rect.top = cirY - radius
        rect.right = cirX + radius
        rect.bottom = cirY + radius
        canvas.drawRect(rect, paint)
    }

    private fun renderX(canvas: Canvas, paint: Paint) {
        canvas.drawLine(rect.left, rect.top, rect.right, rect.bottom, paint)
        canvas.drawLine(rect.left, rect.bottom, rect.right, rect.top, paint)
    }

    private fun renderCross(canvas: Canvas, paint: Paint, radius: Float, cirX: Float, cirY: Float) {
        canvas.drawLine(cirX - radius, cirY, cirX + radius, cirY, paint)
        canvas.drawLine(cirX, cirY - radius, cirX, cirY + radius, paint)
    }

    companion object{
         val plotDotRender:PlotDotRender by lazy { PlotDotRender() }
    }

}

fun Canvas.renderDot( pDot: PlotDot,
    cirX: Float, cirY: Float, paint: Paint
): RectF = plotDotRender.renderDot(this,pDot, cirX, cirY, paint)


